# 排序算法特征主要体现在以下四个方面：执行速度，最坏情况下的复杂度，所需的工作空间以及算法的稳定性
# quicksort（快速排序）	1	 O(n^2)	        0	    不稳定
# mergesort（归并排序）	2	O(n * log(n)）	~n/2	稳定
# heapsort（堆排序）	    3	O(n * log(n))	0	    不稳定

# sort() 对输入数组执行排序，并返回一个数组副本
# a：要排序的数组；
# axis：沿着指定轴进行排序，如果没有指定 axis，默认在最后一个轴上排序
# kind：默认为 quicksort（快速排序）；
# order：若数组设置了字段，则 order 表示要排序的字段。
import numpy as np

a = np.array([[3, 7], [9, 1]])
# 调用sort()函数
print(np.sort(a))  # [[3 7] [1 9]]
# 按列排序：
print(np.sort(a, axis=0))  # [[3 1] [9 7]]
# 设置在sort函数中排序字段
dt = np.dtype([('name', 'S10'), ('age', int)])
a = np.array([("raju", 21), ("anil", 25), ("ravi", 17), ("amar", 27)], dtype=dt)
print(a)  # [(b'raju', 21) (b'anil', 25) (b'ravi', 17) (b'amar', 27)]
# 按name字段排序
print(np.sort(a, order='name'))  # [(b'amar', 27) (b'anil', 25) (b'raju', 21) (b'ravi', 17)]

# argsort() 沿着指定的轴，对输入数组的元素值进行排序，并返回排序后的元素索引数组。
a = np.array([90, 29, 89, 12])
sort_ind = np.argsort(a)
print("打印排序元素索引值", sort_ind)  # [3 1 2 0]
# 使用索引数组对原数组排序
sort_a = a[sort_ind]
for i in sort_ind:
    print(a[i], end=" ")  # 12 29 89 90

# lexsort() 按键序列对数组进行排序，它返回一个已排序的索引数组，类似于 numpy.argsort()。
a = np.array(['a', 'b', 'c', 'd', 'e'])
b = np.array([12, 90, 380, 12, 211])
ind = np.lexsort((a, b))
# 打印排序元素的索引数组
print(ind)  # [0 3 1 4 2]
# 使用索引数组对数组进行排序
for i in ind:
    print(a[i], b[i])
# a 12
# d 12
# b 90
# e 211
# c 380

# nonzero() 该函数从数组中查找非零元素的索引位置
b = np.array([12, 90, 380, 12, 211])
print(b.nonzero())  # (array([0, 1, 2, 3, 4]),)

# where() 的返回值是满足了给定条件的元素索引值。
b = np.array([12, 90, 380, 12, 211])
print(np.where(b > 12))  # (array([1, 2, 4]),)
c = np.array([[20, 24], [21, 23]])
print(np.where(c > 20))  # (array([0, 1, 1]), array([1, 0, 1]))

# extract()该函数的返回值是满足了给定条件的元素值
x = np.arange(9.).reshape(3, 3)
# [[0. 1. 2.]
# [3. 4. 5.]
# [6. 7. 8.]]
# 设置条件选择偶数元素
condition = np.mod(x, 2) == 0
# 输出布尔值数组
print(condition)
# [[ True False  True]
# [False  True False]
# [ True False  True]]
# 按condition提取满足条件的元素值
print(np.extract(condition, x))  # [0. 2. 4. 6. 8.]

# argmax() 该函数返回最大值的的索引
# argmin() 求最小值索引
a = np.array([[30, 40, 70], [80, 20, 10], [50, 90, 60]])
# argmax() 函数
print(np.argmax(a))  # 7
# 将数组以一维展开
print(a.flatten())  # [30 40 70 80 20 10 50 90 60]
# 沿轴 0 的最大值索引：
maxindex = np.argmax(a, axis=0)
print(maxindex)  # [1 2 0]
# 沿轴 1 的最大值索引
maxindex = np.argmax(a, axis=1)
print(maxindex)  # [2 0 1]
# 调用 arming()函数
minindex = np.argmin(b)
print(minindex)
# 展开数组中的最小值：
print(b.flatten()[minindex])
# 沿轴 0 的最小值索引：
minindex = np.argmin(b, axis=0)
print(minindex)
# 沿轴 1 的最小值索引：
minindex = np.argmin(b, axis=1)
print(minindex)
